﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ComponentModel;

using Optimization.Utilities;

namespace Optimization.StandardProblems
{
    /// <summary>
    /// Schwefels function
    /// </summary>
    /// <see cref="http://www-optima.amp.i.kyoto-u.ac.jp/member/student/hedar/Hedar_files/TestGO_files/Page2530.htm"/>
    [IsProblem]
    public class Schwefel : IProblem
    {
        int dim = 2;

        public Schwefel(int Dim)
        {
            this.dim = Dim;
        }

        public Schwefel()
        {
            this.dim = 2;
        }

        //source http://www-optima.amp.i.kyoto-u.ac.jp/member/student/hedar/Hedar_files/TestGO_files/Page2530.htm

        static public double Evaluate(Vector v)
        {
            double result = 0;

            for (int i = 0; i < v.Length; i++)
            {
                //*
                if (Math.Abs(v[i]) > 1000)
                {
                    result = 1e10;
                    return result;
                }
                //*/ 
                double delta = 420.968743;
                delta = 0;
                double solutionI = (v[i] + delta);// -418.9829; 420,968743 418,9828873

                result = result - solutionI * Math.Sin(Math.Sqrt(Math.Abs(solutionI)));
            }

            //result = result + Solution.Length * 418.9829;
            return result;

        }

        [CategoryAttribute("Settings"), DescriptionAttribute("Dimension")]
        public int Dim
        {
            get { return dim; }
            set { this.dim = value; }
        }

        double IProblem.Evaluate(Vector v)
        {
            return Evaluate(v);
        }

        void IProblem.GetBounds(out Vector mins, out Vector maxs)
        {
            mins = -500 * Vector.One(dim);
            maxs = +500 * Vector.One(dim);
        }

        bool IProblem.IsFeasible(Vector v)
        {
            return true;
        }

        Vector IProblem.RandomSolution()
        {
            Vector result = Vector.Random(dim, -500, 500);

            return result;
        }
    }
}
